package com.github.refresh;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PullRefreshLayout extends RefreshLayout {
    private boolean showTimeTips = true;
    private String pullDownRefreshText;
    private String releaseRefreshText;
    private String releaseOpenPageText;
    private String refreshingText;
    private String refreshSuccessText;
    private String refreshErrorText;
    private TextView tv_zr_refresh_header_time;

    public PullRefreshLayout(Context context) {
        super(context);
        init(null);
    }

    public PullRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public PullRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public PullRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs);
    }

    public boolean isShowTimeTips() {
        return showTimeTips;
    }

    public void setShowTimeTips(boolean showTimeTips) {
        this.showTimeTips = showTimeTips;
    }

    private void init(AttributeSet attr) {
        if (attr != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attr, R.styleable.PullRefreshLayout);
            showTimeTips = typedArray.getBoolean(R.styleable.PullRefreshLayout_showTimeTips, true);

            pullDownRefreshText = typedArray.getString(R.styleable.PullRefreshLayout_pullDownRefreshText);
            releaseRefreshText = typedArray.getString(R.styleable.PullRefreshLayout_releaseRefreshText);
            releaseOpenPageText = typedArray.getString(R.styleable.PullRefreshLayout_releaseOpenPageText);
            refreshingText = typedArray.getString(R.styleable.PullRefreshLayout_refreshingText);
            refreshSuccessText = typedArray.getString(R.styleable.PullRefreshLayout_refreshSuccessText);
            refreshErrorText = typedArray.getString(R.styleable.PullRefreshLayout_refreshErrorText);

            typedArray.recycle();
        }

        if (TextUtils.isEmpty(pullDownRefreshText)) {
            pullDownRefreshText = getContext().getString(R.string.zr_pull_down_to_refresh);
        }
        if (TextUtils.isEmpty(releaseRefreshText)) {
            releaseRefreshText = getContext().getString(R.string.zr_release_to_refresh);
        }
        if (TextUtils.isEmpty(releaseOpenPageText)) {
            releaseOpenPageText = getContext().getString(R.string.zr_release_to_open_age);
        }
        if (TextUtils.isEmpty(refreshingText)) {
            refreshingText = getContext().getString(R.string.zr_refreshing);
        }
        if (TextUtils.isEmpty(refreshSuccessText)) {
            refreshSuccessText = getContext().getString(R.string.zr_refresh_success);
        }
        if (TextUtils.isEmpty(refreshErrorText)) {
            refreshErrorText = getContext().getString(R.string.zr_refresh_error);
        }


        setHeader();
    }

    private PullDownListener pullDownListener;

    @Override
    public void setListener(PullDownListener listener) {
        pullDownListener = listener;
    }

    private void setHeader() {
        View headerView = LayoutInflater.from(getContext()).inflate(R.layout.zr_refresh_default_header, null);

        ImageView iv_zr_refresh_header_arrow = headerView.findViewById(R.id.iv_zr_refresh_header_arrow);

        ProgressBar pb_zr_refresh_header_load = headerView.findViewById(R.id.pb_zr_refresh_header_load);
        TextView tv_zr_refresh_header_text = headerView.findViewById(R.id.tv_zr_refresh_header_text);
        tv_zr_refresh_header_time = headerView.findViewById(R.id.tv_zr_refresh_header_time);

        super.setListener(new PullDownListener() {
            @Override
            public void pullDownDistance(RefreshLayout layout, PullDown pullDown) {
                RefreshStatus status = pullDown.status;
                updateRefreshTime(status);
                switch (status) {
                    case DEF:
                    case PullDown:
                    case PreRefresh:
                        setHeaderArrow(status, pullDown.preTopDistance, pullDown.topDistance, iv_zr_refresh_header_arrow);
                        INVISIBLE(pb_zr_refresh_header_load);
                        showHeaderTips(status, tv_zr_refresh_header_text);
                        break;
                    case Refresh:
                        iv_zr_refresh_header_arrow.clearAnimation();
                        INVISIBLE(iv_zr_refresh_header_arrow);
                        GONE(tv_zr_refresh_header_time);
                        VISIBLE(pb_zr_refresh_header_load);
                        showHeaderTips(status, tv_zr_refresh_header_text);
                        break;
                    case PreOpenPage:
                    case OpenPage:
                    case RefreshSuccess:
                    case RefreshError:
                        iv_zr_refresh_header_arrow.clearAnimation();
                        INVISIBLE(iv_zr_refresh_header_arrow);
                        GONE(tv_zr_refresh_header_time);
                        INVISIBLE(pb_zr_refresh_header_load);
                        showHeaderTips(status, tv_zr_refresh_header_text);
                        if (status == RefreshStatus.RefreshSuccess) {
                            saveLastTime();
                        }
                        break;

                }
                if (pullDownListener != null) {
                    pullDownListener.pullDownDistance(layout, pullDown);
                }
            }
        });
        setHeaderView(headerView);
    }

    private boolean isUpdateTime;
    private long lastRefreshTime;

    private void updateRefreshTime(RefreshStatus status) {
        if (status == RefreshStatus.PullDown || status == RefreshStatus.PreRefresh) {
            if (isUpdateTime) {
                return;
            }
            startUpdateTime();
        } else {
            stopUpdateTime();
        }
    }

    private void startUpdateTime() {
        if (showTimeTips) {
            long preTime = updateTime();
            if (preTime <= 0) {
                /*如果第一次下拉，没有时间*/
                GONE(tv_zr_refresh_header_time);
                return;
            }
            isUpdateTime = true;
            post(updateTimeRunnable);

            VISIBLE(tv_zr_refresh_header_time);
        } else {
            GONE(tv_zr_refresh_header_time);
        }
    }

    private void stopUpdateTime() {
        isUpdateTime = false;
        removeCallbacks(updateTimeRunnable);
    }

    private void saveLastTime() {
        getSP().edit().putLong("lastRefreshTimeKey", System.currentTimeMillis()).apply();
    }

    public long getLastRefreshTime() {
        lastRefreshTime = getSP().getLong("lastRefreshTimeKey", 0);
        return lastRefreshTime;
    }

    private StringBuffer stringBuffer;

    private long updateTime() {
        long currentTimeMillis = System.currentTimeMillis();
        lastRefreshTime = getLastRefreshTime();
        if (lastRefreshTime > 0) {
            if (stringBuffer == null) {
                stringBuffer = new StringBuffer();
            } else {
                stringBuffer.delete(0, stringBuffer.length());
            }
            long timeIntervalSecond = (currentTimeMillis - lastRefreshTime) / 1000;

            stringBuffer.append(getContext().getString(R.string.zr_last_update));
            if (timeIntervalSecond < 60) {
                /*小于一分钟*/
                stringBuffer.append(timeIntervalSecond);
                stringBuffer.append(getContext().getString(R.string.zr_seconds_ago));
            } else if (timeIntervalSecond < 3600) {
                /*小于一小时*/
                stringBuffer.append(timeIntervalSecond / 60);
                stringBuffer.append(getContext().getString(R.string.zr_minutes_ago));
            } else if (timeIntervalSecond < 86400) {
                /*小于一天*/
                stringBuffer.append(timeIntervalSecond / 3600);
                stringBuffer.append(getContext().getString(R.string.zr_hours_ago));
            } else {
                /*大于一天*/
                stringBuffer.append(timeIntervalSecond / 86400);
                stringBuffer.append(getContext().getString(R.string.zr_days_ago));
            }
            if (tv_zr_refresh_header_time != null) {
                tv_zr_refresh_header_time.setText(stringBuffer.toString());
            }
        }
        return lastRefreshTime;
    }

    private Runnable updateTimeRunnable = new Runnable() {
        @Override
        public void run() {
            if (!isUpdateTime) {
                return;
            }
            updateTime();
            postDelayed(this, 1000 - System.currentTimeMillis() % 1000);
        }
    };
    private SharedPreferences refreshLayoutTime;

    private SharedPreferences getSP() {
        if (refreshLayoutTime == null) {
            refreshLayoutTime = getContext().getSharedPreferences("PullRefreshLayoutTime", Context.MODE_PRIVATE);
        }
        return refreshLayoutTime;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopUpdateTime();
    }

    private RotateAnimation reverseAnimation;
    private RotateAnimation pullDownAnimation;

    private RotateAnimation getReverseAnimation() {
        if (reverseAnimation == null) {
            reverseAnimation = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            reverseAnimation.setInterpolator(new LinearInterpolator());
            reverseAnimation.setDuration(150);
            reverseAnimation.setFillAfter(true);
        }
        return reverseAnimation;
    }

    private RotateAnimation getPullDownAnimation() {
        if (pullDownAnimation == null) {
            pullDownAnimation = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            pullDownAnimation.setInterpolator(new LinearInterpolator());
            pullDownAnimation.setDuration(10);
            pullDownAnimation.setFillAfter(true);
        }
        return pullDownAnimation;
    }

    private void setHeaderArrow(RefreshStatus status, int preTopDistance, int topDistance, ImageView iv_zr_refresh_header_arrow) {
        VISIBLE(iv_zr_refresh_header_arrow);
        if (status == RefreshStatus.PullDown) {
            VISIBLE(iv_zr_refresh_header_arrow);
            if (preTopDistance >= getHelper().getPullDownHeaderHeightRefresh() && topDistance < getHelper().getPullDownHeaderHeightRefresh()) {
                /*刷新变下拉*/
                iv_zr_refresh_header_arrow.clearAnimation();
                iv_zr_refresh_header_arrow.startAnimation(getPullDownAnimation());
            }
        } else if (status == RefreshStatus.PreRefresh) {
            VISIBLE(iv_zr_refresh_header_arrow);
            if (preTopDistance < getHelper().getPullDownHeaderHeightRefresh() && topDistance >= getHelper().getPullDownHeaderHeightRefresh()) {
                /*下拉变刷新*/
                iv_zr_refresh_header_arrow.clearAnimation();
                iv_zr_refresh_header_arrow.startAnimation(getReverseAnimation());
            }
        }
    }

    private void showHeaderTips(RefreshStatus status, TextView tv_zr_refresh_header_text) {
        if (status == RefreshStatus.PullDown) {
            tv_zr_refresh_header_text.setText(getPullDownRefreshText());
        } else if (status == RefreshStatus.PreRefresh) {
            tv_zr_refresh_header_text.setText(getReleaseRefreshText());
        } else if (status == RefreshStatus.Refresh) {
            tv_zr_refresh_header_text.setText(getRefreshingText());
        } else if (status == RefreshStatus.RefreshSuccess) {
            tv_zr_refresh_header_text.setText(getRefreshSuccessText());
        } else if (status == RefreshStatus.RefreshError) {
            tv_zr_refresh_header_text.setText(getRefreshErrorText());
        } else if (status == RefreshStatus.PreOpenPage || status == RefreshStatus.OpenPage) {
            tv_zr_refresh_header_text.setText(getReleaseOpenPageText());
        }
        VISIBLE(tv_zr_refresh_header_text);
    }

    public String getPullDownRefreshText() {
        if (TextUtils.isEmpty(pullDownRefreshText)) {
            pullDownRefreshText = getContext().getString(R.string.zr_pull_down_to_refresh);
        }
        return pullDownRefreshText;
    }

    public void setPullDownRefreshText(String pullDownRefreshText) {
        this.pullDownRefreshText = pullDownRefreshText;
    }

    public String getReleaseRefreshText() {
        if (TextUtils.isEmpty(releaseRefreshText)) {
            releaseRefreshText = getContext().getString(R.string.zr_release_to_refresh);
        }

        return releaseRefreshText;
    }

    public void setReleaseRefreshText(String releaseRefreshText) {
        this.releaseRefreshText = releaseRefreshText;
    }

    public String getReleaseOpenPageText() {
        if (TextUtils.isEmpty(releaseOpenPageText)) {
            releaseOpenPageText = getContext().getString(R.string.zr_release_to_open_age);
        }

        return releaseOpenPageText;
    }

    public void setReleaseOpenPageText(String releaseOpenPageText) {
        this.releaseOpenPageText = releaseOpenPageText;
    }

    public String getRefreshingText() {
        if (TextUtils.isEmpty(refreshingText)) {
            refreshingText = getContext().getString(R.string.zr_refreshing);
        }

        return refreshingText;
    }

    public void setRefreshingText(String refreshingText) {
        this.refreshingText = refreshingText;
    }

    public String getRefreshSuccessText() {
        if (TextUtils.isEmpty(refreshSuccessText)) {
            refreshSuccessText = getContext().getString(R.string.zr_refresh_success);
        }
        return refreshSuccessText;
    }

    public void setRefreshSuccessText(String refreshSuccessText) {
        this.refreshSuccessText = refreshSuccessText;
    }

    public String getRefreshErrorText() {
        if (TextUtils.isEmpty(refreshErrorText)) {
            refreshErrorText = getContext().getString(R.string.zr_refresh_error);
        }
        return refreshErrorText;
    }

    public void setRefreshErrorText(String refreshErrorText) {
        this.refreshErrorText = refreshErrorText;
    }

    private void showTime(TextView tv_zr_refresh_header_time) {
        if (showTimeTips) {

            VISIBLE(tv_zr_refresh_header_time);
        } else {
            GONE(tv_zr_refresh_header_time);
        }
    }

    public static void VISIBLE(View... views) {
        if (views == null) {
            return;
        }
        for (View v : views) {
            v.setVisibility(VISIBLE);
        }
    }

    public static void INVISIBLE(View... views) {
        if (views == null) {
            return;
        }
        for (View v : views) {
            v.setVisibility(INVISIBLE);
        }
    }

    public static void GONE(View... views) {
        if (views == null) {
            return;
        }
        for (View v : views) {
            v.setVisibility(GONE);
        }
    }

}